package com.sgl.gk.service.impl;

import com.sg.comm.common.Ret;
import com.sg.comm.opcuav2.NodeDTOV2;
import com.sg.comm.opcuav2.OpcUaReadReqV2;
import com.sg.comm.service.OpcUaServiceV2;
import com.sgl.common.core.controller.BaseController;
import com.sgl.common.core.domain.AjaxResult;
import com.sgl.common.utils.StringUtils;
import com.sgl.gk.controller.GkStationController;
import com.sgl.gk.controller.vo.GkProductionLineAndStationVo;
import com.sgl.gk.controller.vo.GkProductionLineVo;
import com.sgl.gk.domain.*;
import com.sgl.gk.mapper.*;
import com.sgl.gk.scheduled.ScheduledTask;
import com.sgl.gk.service.GkProductionLineService;
import com.sgl.gk.service.GkStationConfigureTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GkProductionLineServiceImpl extends BaseController implements GkProductionLineService {

    @Autowired
    GkProductionLineMapper gkProductionLineMapper;

    @Autowired
    GkStationMapper gkStationMapper;

    @Autowired
    GkStationServiceImpl gkStationService;

    @Autowired
    GkStationConfigurationMapper gkStationConfigurationMapper;

    @Autowired
    GkStationConfigureTemplateMapper gkStationConfigureTemplateMapper;

    @Autowired
    GkStationConfigureTemplateService gkStationConfigureTemplateService;

    @Autowired
    GkSignalCommunicationMapper gkSignalCommunicationMapper;

    @DubboReference(version = "1.0.0", url = "dubbo://127.0.0.1:20880", check = false ,timeout = 15000)
    private OpcUaServiceV2 opcUaServiceV2;

    @Value("${communication.mode}")
    public String communication;

    @Override
    public  List<GkProductionLineVo> list(GkProductionLine gkProductionLine) {
        gkProductionLine.setName(StringUtils.trim(gkProductionLine.getName()));
        List<GkProductionLineVo> list = gkProductionLineMapper.list(gkProductionLine);
        List<Long> productionLineIds = list.stream().map(GkProductionLineVo::getId).collect(Collectors.toList());
        if (productionLineIds==null||productionLineIds.size()==0){
            return list;
        }
        List<GkStation> gkStations = gkStationMapper.selectByProductionIds(productionLineIds);
        Map<Long, List<GkStation>> listMap = gkStations.parallelStream().collect(Collectors.groupingBy(GkStation::getProductionLineId));
        List<Long> signalIds = gkStations.stream().map(GkStation::getSignalCommunicationId).collect(Collectors.toList());
        List<GkSignalCommunication> gkSignalCommunicationList = gkSignalCommunicationMapper.selectInfoByIds(signalIds);
        List<GkStationConfigureTemplate> gkStationConfigureTemplates = gkStationConfigureTemplateMapper.selectInfoByProductionLineIds(productionLineIds.toArray(new Long[0]));
        Map<Long, List<GkStationConfigureTemplate>> collect = gkStationConfigureTemplates.parallelStream().collect(Collectors.groupingBy(GkStationConfigureTemplate::getProductionLineId));
        for (GkProductionLineVo gkProductionLineVo : list) {
            gkProductionLineVo.setTemplateNum(collect.get(gkProductionLineVo.getId())==null?0:collect.get(gkProductionLineVo.getId()).size());
            List<GkStation> gkStations1 = listMap.get(gkProductionLineVo.getId());
            List<Long> signalIds1 = new ArrayList<>();
            for (GkStation gkStation : gkStations1) {
                if (gkStation.getSignalCommunicationId()!=null){
                    signalIds1.add(gkStation.getSignalCommunicationId());
                }
            }
            if (signalIds1.size()==0){
                gkProductionLineVo.setStatus(0);
            }
            for (Long signalId : signalIds1) {
                if (signalId!=null) {
                    for (GkSignalCommunication gkSignalCommunication : gkSignalCommunicationList) {
                        if (signalId.longValue() == gkSignalCommunication.getId().longValue()) {
                            if (communication.equals("plc")) {
                                OpcUaReadReqV2 opcUaReadReqV2 = new OpcUaReadReqV2();
                                opcUaReadReqV2.setUid(gkSignalCommunication.getCommunicationProtocol());
                                Boolean isConn = null;
                                try {
                                    isConn = opcUaServiceV2.isConn(opcUaReadReqV2).getData().getIsConn();
                                } catch (Exception e) {
                                    log.error(e.getMessage());
                                }
                                if (isConn!=null&&isConn) {
                                    gkProductionLineVo.setStatus(1);
                                } else {
                                    gkProductionLineVo.setStatus(0);
                                }
                            } else if (communication.equals("socket")) {
                                BufferedWriter bufferedWriter = ScheduledTask.bufferedWriter;
                                BufferedReader bufferedReader = ScheduledTask.bufferedReader;
                                try {
                                    bufferedWriter.write(gkSignalCommunication.getCommunicationProtocol() + "\n");
                                    bufferedWriter.flush();
                                    String s = bufferedReader.readLine();
                                    if (s.equals("NO")) {
                                        gkProductionLineVo.setStatus(0);
                                    } else {
                                        gkProductionLineVo.setStatus(1);
                                    }
                                } catch (IOException e) {
                                    log.error("socket连接异常");
                                }
                            } else {
                                gkProductionLineVo.setStatus(0);
                            }
                        }
                    }
                }else {
                    gkProductionLineVo.setStatus(0);
                }
            }
        }
        return list;
    }

    @Override
    @Transactional
    public AjaxResult add(GkProductionLine gkProductionLine) {
        gkProductionLine.setName(gkProductionLine.getName().trim());
        gkProductionLine.setCode(gkProductionLine.getCode().trim());
        gkProductionLine.setCreateAt(new Date());
        gkProductionLine.setLastModifyAt(new Date());
        int row = gkProductionLineMapper.add(gkProductionLine);
        Long productLineId = gkProductionLineMapper.MaxId();
        // 新增默认工位
        GkStation gkStation = new GkStation();
        gkStation.setName("默认工位");
        gkStation.setProductionLineId(productLineId);
        gkStation.setDefaultStation(1);
        gkStation.setCode("");
        gkStation.setCreateAt(new Date());
        gkStation.setLastModifyAt(new Date());
        gkStation.setConfigureType(1);
        gkStationMapper.add(gkStation);
        Long stationId = gkStationMapper.MaxId();
        // 新增默认工位变量
        List<GkStationConfiguration> gkStationConfigurationList = new ArrayList<>();
        GkStationConfiguration gkStationConfiguration = new GkStationConfiguration();
        gkStationConfiguration.setStationId(stationId);
        gkStationConfiguration.setType(1);
        gkStationConfiguration.setDefaultValue("");
        gkStationConfiguration.setDisplayName("ProductType");
        gkStationConfiguration.setVariableName("ProductType");
        gkStationConfiguration.setVariableIndex(1);
        gkStationConfiguration.setToUse(1);
        gkStationConfiguration.setDataType("string");
        gkStationConfiguration.setResultConversion(0);
        String s = "";
        gkStationConfiguration.setZeroValue(s);
        gkStationConfiguration.setOneValue(s);
        gkStationConfiguration.setTwoValue(s);
        gkStationConfiguration.setThreeValue(s);
        gkStationConfiguration.setFourValue(s);
        gkStationConfiguration.setFiveValue(s);
        gkStationConfiguration.setCheckLength(16);
        gkStationConfiguration.setCreateAt(new Date());
        gkStationConfiguration.setLastModifyAt(new Date());
        GkStationConfiguration gkStationConfiguration1 = new GkStationConfiguration();
        gkStationConfiguration1.setStationId(stationId);
        gkStationConfiguration1.setType(1);
        gkStationConfiguration1.setDataType("byte");
        gkStationConfiguration1.setDisplayName("ProductNum");
        gkStationConfiguration1.setVariableName("ProductNum");
        gkStationConfiguration1.setVariableIndex(2);
        gkStationConfiguration1.setDefaultValue("0");
        gkStationConfiguration1.setToUse(1);
        gkStationConfiguration1.setZeroValue(s);
        gkStationConfiguration1.setOneValue(s);
        gkStationConfiguration1.setTwoValue(s);
        gkStationConfiguration1.setThreeValue(s);
        gkStationConfiguration1.setFourValue(s);
        gkStationConfiguration1.setFiveValue(s);
        gkStationConfiguration1.setResultConversion(0);
        gkStationConfiguration1.setCreateAt(new Date());
        gkStationConfiguration1.setLastModifyAt(new Date());
        gkStationConfigurationList.add(gkStationConfiguration);
        gkStationConfigurationList.add(gkStationConfiguration1);
        gkStationConfigurationMapper.saveList(gkStationConfigurationList);
        if (row>0){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @Override
    public AjaxResult edit(GkProductionLine gkProductionLine) {
        gkProductionLine.setName(gkProductionLine.getName().trim());
        gkProductionLine.setCode(gkProductionLine.getCode().trim());
        int row = gkProductionLineMapper.edit(gkProductionLine);
        if (row>0){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @Override
    public AjaxResult removeByIds(Long[] ids) {
        int row = gkProductionLineMapper.removeByIds(ids);
        List<GkStation> gkStations = gkStationMapper.selectByProductionIds(Arrays.asList(ids));
        List<Long> stationIds = gkStations.stream().map(gkStation -> gkStation.getId()).collect(Collectors.toList());
        if (stationIds.size()>0) {
            gkStationService.removeByIds(stationIds.toArray(new Long[0]));
        }
        // 产线删除对应的模板也删除
        row = gkStationConfigureTemplateService.removeByProductionLineIds(ids);
        if (row>0){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @Transactional
    @Override
    public AjaxResult selectInfoByIds() {
        List<GkProductionLineAndStationVo> list = gkProductionLineMapper.selectAllIdAndNameInfo();
        List<Long> productionIds = list.stream().map(GkProductionLineAndStationVo::getProductionLineId).collect(Collectors.toList());
        List<GkStation> gkStations =  gkStationMapper.selectByProductionIds(productionIds);
        for (GkProductionLineAndStationVo gkProductionLineAndStationVo : list) {
            List<GkProductionLineAndStationVo.Station> stationList = new ArrayList<>();
            for (GkStation gkStation : gkStations) {
                GkProductionLineAndStationVo.Station station = new GkProductionLineAndStationVo.Station();
                if (gkStation.getProductionLineId().equals(gkProductionLineAndStationVo.getProductionLineId())){
                    station.setStationId(gkStation.getId());
                    station.setStationName(gkStation.getName());
                    stationList.add(station);
                }
            }
            gkProductionLineAndStationVo.setStationList(stationList);
        }
        return AjaxResult.success(list);
    }


}
